#!/usr/bin/python
# -*- coding: UTF-8 -*-

import smtplib  
import email
import os
from smtplib import SMTP_SSL
from email.mime.text import MIMEText
from email.header import Header


class Mail(object):

    def __init__(self, user, password, **kwargs):
        self.user = user
        self.password = password
        self.myname = None
        self.mail_server = None
        self.mail_port = 0
        self.to_addrs = []
        self.timeout = 5
        self.use_ssl = False
        self.use_tls = True
        self.attachments = []

        self.__dict__.update(kwargs)

    def sendmail(self, subject, content):  
        """send email with smtp.

        :param subject: string|the email's subject
        :param connect: string|the email's connect
        """
        
        msg = self.pack_msg(subject, content)
        
        return self._send_mail(msg)

    def _send_mail(self, msg):
        if self.use_ssl:
            server = SMTP_SSL(timeout=self.timeout)  
        else:
            server = smtplib.SMTP(timeout=self.timeout)  

        try:  
            server.connect(host=self.mail_server, port=str(self.mail_port)) 
            server.login(self.user, self.password)  
            res = server.sendmail(self.from_addr, self.to_addrs, msg.as_string())  
            return res 
        except Exception, e:  
            raise e
        finally:
            if getattr(server, 'sock', None):
                server.close()  

    def pack_msg(self, subject, content):
        '''

        :param subject: string| mail's subject
        :param content: string| mail's content
        :return: the mail content include attachments file
        '''
        msg = email.MIMEMultipart.MIMEMultipart()  
        content_msg = MIMEText(content, _subtype='plain', _charset='utf-8')
        subject = Header(subject, 'utf-8')
        msg.attach(content_msg)

        msg = self.pack_attach(msg)

        msg['Subject'] = subject  
        msg['From'] = self.from_addr

        self.to_addrs = [x for x in self.to_addrs if x not in ['None', None]]
        msg['To'] = ",".join(set(self.to_addrs))
        return msg

    def pack_attach(self, msg):
        '''

        :param attachments: list| mail's attachments
        :return: the mail content include attachments file
        '''
        if not self.attachments:
            return msg

        contype = 'application/octet-stream'  
        maintype, subtype = contype.split('/', 1) 
        for attachment in self.attachments:
            with open(attachment, 'rb') as data:
                file_msg = email.MIMEBase.MIMEBase(maintype, subtype)  
                file_msg.set_payload(data.read( ))  

                email.Encoders.encode_base64(file_msg)  
                basename = os.path.basename(attachment)  
                file_msg.add_header('Content-Disposition', 'attachment', filename=basename)

                msg.attach(file_msg)  
        return msg

    @property
    def from_addr(self):
        username = self.user.split('@')[0]
        myname = self.myname or username
        from_addr = '%s <%s>' % (myname, self.user)
        return from_addr


if __name__ == '__main__':  
    mail = Mail('redmine@fusionstack.cn', 'mineredHywj123')
    mail.mail_server = "smtp.exmail.qq.com"
    mail.myname = 'fusionstor'
    mail.mail_port = 465
    mail.use_ssl = True
    mail.attachments = ['/root/git/fusionstor/ump/Ump/common/config.py', '/root/git/fusionstor/ump/Ump/common/mail.py']
    mail.to_addrs = ['redmine@fusionstack.cn']
    mail.sendmail('Attach Test', 'dddd')
